{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Understanding Word Vectors usage with Spacy Word and Sentence Similarity\n",
    "\n",
    "## [Link to my Youtube Video Explaining this whole Notebook](https://www.youtube.com/watch?v=SzSANHjYhfg&list=PLxqBkZuBynVTn2lkHNAcw6lgm1MD5QiMK&index=6)\n",
    "\n",
    "[![Imgur](https://imgur.com/E1fN7T4.png)](https://www.youtube.com/watch?v=SzSANHjYhfg&list=PLxqBkZuBynVTn2lkHNAcw6lgm1MD5QiMK&index=6)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A word vector is basically a dense representation of a word.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is more than one way to produce word vectors. Let's look at the most popular pretrained vectors and how they are trained:\n",
    "\n",
    "### word2vec\n",
    "\n",
    "### Glove vectors\n",
    "\n",
    "### fastText"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.6) or chardet (3.0.4) doesn't match a supported version!\n",
      "  warnings.warn(\"urllib3 ({}) or chardet ({}) doesn't match a supported \"\n"
     ]
    }
   ],
   "source": [
    "import spacy\n",
    "\n",
    "# nlp = spacy.load(\"en_core_web_sm\")\n",
    "nlp = spacy.load(\"en_core_web_md\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(300,)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "doc = nlp(\"I bought BitCoin\")\n",
    "\n",
    "# print(doc[1])\n",
    "\n",
    "doc[1].vector\n",
    "\n",
    "doc[1].vector.shape\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### out-of-vocabulary\n",
    "\n",
    "\n",
    "Only the words in the model's vocabulary have vectors; words that are not in the \n",
    "vocabulary are called OOV (out-of-vocabulary) words. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False True\n",
      "False True\n",
      "False True\n",
      "True False\n",
      "False True\n"
     ]
    }
   ],
   "source": [
    "doc = nlp(\"You went there afskfsd.\")\n",
    "\n",
    "for token in doc:\n",
    "    print(token.is_oov, token.has_vector)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You\n",
      "went\n",
      "there\n",
      "afskfsd\n",
      ".\n"
     ]
    }
   ],
   "source": [
    "doc = nlp(\"You went there afskfsd.\")\n",
    "\n",
    "for token in doc:\n",
    "    print(token)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The similarity method\n",
    "\n",
    "In spaCy, every container type object has a similarity method that allows us to calculate the semantic similarity of other container objects by comparing their word vectors.\n",
    "\n",
    "\n",
    "https://spacy.io/usage/linguistic-features#similarity-expectations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.6873385906219482\n"
     ]
    }
   ],
   "source": [
    "doc1 = nlp(\"I bought BitCoin\")\n",
    "\n",
    "doc2 = nlp(\"I purchased Stock\")\n",
    "\n",
    "print(doc1[1:3].similarity(doc2[1:4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Limitation of Similarity\n",
    "\n",
    "These two sentences should not be 90% similar they have very different meanings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9348879165307562\n"
     ]
    }
   ],
   "source": [
    "search_doc = nlp(\"This was very strange argument between american and british person\")\n",
    "\n",
    "main_doc = nlp(\"He was from Japan, but a true English gentleman in my eyes.\")\n",
    "\n",
    "print(main_doc.similarity(search_doc))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.7954015264714663\n"
     ]
    }
   ],
   "source": [
    "search_doc = nlp(\"This was very strange argument between american and british person\")\n",
    "\n",
    "main_doc = nlp(\"He was from Japan, but a true English gentleman in my eyes, and another one of the reasons as to why I liked going to school.\")\n",
    "\n",
    "search_doc_no_stop_words = nlp(' '.join([str(t) for t in search_doc if not t.is_stop]))\n",
    "\n",
    "main_doc_no_stop_words = nlp(' '.join([str(t) for t in main_doc if not t.is_stop]))\n",
    "\n",
    "print(search_doc_no_stop_words.similarity(main_doc_no_stop_words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Distance Visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABIAAAANOCAYAAABp7XcQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABq3UlEQVR4nOzdebRd88H/8c++yU1yM0siZEA0iMdQwlUpoYRIiCEx0yKoTniqKsqDCkVVaGlVW9pKB60hJFFaU9tUESVpWvNUiRCpIFIiN2Q4vz/U+fU2MeZmsPN6rZW17vnu6XvOWs+w3vZ376JSqQQAAACA8qpZ2RMAAAAAYPkSgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkmu+Mi7apUuXSq9evVbGpQEAAABKafLkyS9VKpU1l7ZtpQSgXr16ZdKkSSvj0gAAAAClVBTFM++0zRIwAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAABWayNHjkxRFNlwww2Xun3DDTdMURQZOXLkip0YADQhAQgAgNVeq1atMnXq1EyaNKnR+P33359p06alVatWK2lmANA0BCAAAFZ7bdq0yYABA3L11Vc3Gr/66qszYMCAtGnTZiXNDACahgAEAABJDj744Fx77bWpVCpJkkqlkmuvvTYHH3zwEvtee+212XzzzdOyZcuss846Oe2007Jw4cLq9pEjR6ZLly5LHFcURS699NLq5xtvvDFbb7112rRpkzXWWCPbbrtt/vSnP1W3L168OOeff3422GCDtGzZMhtttFF+9rOfNeXXBmA1IQABAECSfffdNy+88ELuuuuuJMmf//znvPjii9l3330b7XfbbbfloIMOylZbbZXx48fn+OOPz4UXXpjjjjvuA13vH//4R/bff/8MGDAgv/nNb3LVVVdlzz33zOzZs6v7HH/88TnnnHPyuc99LjfffHOGDRuWo446KjfddNOyf2EAVivNV/YEAABgVdCxY8cMHjw4V199dXbYYYdcffXVGTx4cDp06NBov69//evZaaedqnfiDB48OEly6qmn5vTTT0/Pnj3f1/WmTJmSdu3aZdSoUdWxPfbYo/r3U089lR/84Ae58sorc8QRRyRJdt1118ycOTNnnXVW9txzz2X6vgCsXtwBBAAA/3bwwQdnzJgxeeONNzJmzJglln8tWrQof/3rX3PAAQc0Gj/ooIOyePHiTJw48X1fa/PNN8+//vWvHHHEEbntttvy+uuvN9r++9//PjU1NRk2bFgWLlxY/bfLLrvkb3/7WxYtWvThvygAqx0BCAAA/m3vvffO3Llzc9ppp+X111/PXnvt1Wj7Sy+9lAULFmSttdZqNP725/9cvvVe+vTpk/Hjx+fpp5/OHnvskS5duuTQQw/Niy++WL3WokWL0qFDh9TW1lb/DR8+PAsXLszMmTOX8dsCsDqxBAwAgNXKuCkzMurWx/P8nIZ071iXdWa+Wt3Wpk2b7LnnnvnOd76TAw44YIm3f3Xp0iW1tbWZNWtWo/EXXnghSdKpU6ckb71W/s0332y0zyuvvLLEXIYMGZIhQ4bkX//6V26++eaccMIJOf7443P11VenU6dOad68ee6+++7U1Cz53227du364X4AAFZLAhAAAKuNcVNm5NQbHkzDgreWT82Y05DHH52VNxctru7zxS9+MW+88Ua+8IUvLHF8s2bNsvXWW+e6667LF7/4xer4tddem5qamnzyk59MkvTs2TOvvfZaZsyYkR49eiR56+HR76RDhw459NBD86c//am6jGzAgAFZtGhR/vWvf2XgwIHL/uUBWK0JQAAArDZG3fp4Nf68beHixWl48/+P7bTTTtlpp53e8RxnnXVWBg0alCOPPDIHH3xwHnzwwZxxxhk55phjqg+AHjx4cOrq6nLUUUflq1/9aqZOnZof/vCHjc7zox/9KBMnTszgwYPTvXv3PPnkk7nuuuty+OGHJ3lridgXvvCFHHzwwTn55JNTX1+f+fPn5+GHH84TTzyRH//4x030qwCwOhCAAABYbTw/p2Gp44sr7/8cu+22W66++uqcc845ueqqq9K1a9d89atfzVlnnVXdp0uXLrn++utz0kknZejQodl6663zq1/9Kptsskl1n49//OO58cYbc+KJJ2b27Nnp1q1bjjnmmJx99tnVfb7//e9no402yhVXXJGvf/3rad++fTbZZJMcffTRH/zLA7BaKyqVD/B/7ZpIfX19ZdKkSSv8ugAArN62P/8PmbGUCNSjY13uPmXASpgRADSdoigmVyqV+qVt8xYwAABWGyMG9UldbbNGY3W1zTJiUJ+VNCMAWDEsAQMAYLUxtO9bD2T+z7eAjRjUpzoOAGUlAAEAsFoZ2reH4APAascSMAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAgOXq7LPPTo8ePVJTU5O6uroURZHa2tr06NEj+++/f2655ZZ3PHbatGkpiiI33XRTdWynnXbK/vvv/67XnDt3boqiyOjRo6tjr7/+eg4++OB07ty5um3kyJHp0qXL+/4uo0ePTlEUmTt37vs+BgBgVdB8ZU8AACivSZMm5cwzz8x2222XmTNnZrfddssnP/nJbL311vnnP/+Zq6++Orvvvnueeuqp9O7de7nO5Qc/+EF+85vf5Oc//3l69OiR3r1754033shee+21XK8LALAqEIAAgOXmscceS5Lcc889ufLKKzN8+PBG2w877LD85je/SV1d3QqZS58+fbLffvs1Gu/Zs+dyvzYAwMpmCRgAsFwMHz48hx12WPXzkUcemQkTJqQoijz00EPV8VmzZmXXXXdNXV1dunTpkh49eqRLly5p1apV9t577yTJvHnz8vnPfz4dOnTIxIkT88gjj2Tx4sXVc1x//fXZaKONUldXlx133LEant7Wq1ev/OQnP8mUKVNSFEWKokiSJZaALViwICeddFLWXXfdtGzZMt27d8+wYcPy5ptvNjrf1KlTM3DgwLRp0yYbb7xxbrjhhqb74QAAlgMBCABYLs4444z83//9X5Lk05/+dCZOnJhXX3210T533nlnvvCFL+Swww7L7373u2y66aZ58cUXc9hhh2Xs2LHp1q1bkuTLX/5y2rZtmzFjxmSttdbKo48+mjFjxiRJ/vrXv+aggw7KFltskRtuuCF77bVXDjzwwEbXGTt2bPbYY49svPHGmThxYiZOnLjUOX/zm9/MVVddlW984xu5/fbbc/HFF6dDhw5ZtGhRo/0OPfTQ7L333hk7dmw23HDDHHzwwXnuueea5HcDAFgeLAEDAJaL3r17p2vXrkmSbbbZJv369cuECROSJJVKJQsXLsy9996bzTffPKecckoee+yx/PnPf86VV16ZI444IknSp0+f9O7dO0VR5KKLLkqSfOxjH8urr76aG264IQceeGDOP//8bLTRRrn22mtTFEV23333vPnmmzn99NOrc+nbt2/WXHPNvPDCC+nXr987zvm+++7LoYceWr1+kiViUpJ85StfyVFHHZUk2XrrrbPWWmvlpptuyhe+8IVl+9EAAJYTdwABAMvd20uu3vazn/0stbW1+drXvpYpU6ZkwIAB+cUvfpFKpZIDDjigul9NzVv/r8rLL7/c6Pj27dtX77i57777svfeeze6xr777vuh5rnllltm9OjRueCCC/LAAw+kUqksdb/ddtut+nfnzp3TtWtXdwABAKs0AQgAWG7atm2bJHn++ecbje+55565//77c//99ydJ/vGPf+T8889PkowYMSKvv/56o/3ffPPNvPHGG9XPNTU1mT9/fpLkn//8Z/VOo7f99+f36/TTT8+xxx6byy67LFtssUXWWWedXHLJJUvs17Fjx0afW7RoUZ0PAMCqyBIwAKBJnT7uwfz6L89mUaWSeQ++9bDn3//+94326dKlSzbbbLPq55NPPjlJcvzxx+fKK69Mu3btqkEoSVq2bJmWLVsu9Xprr712Zs2a1Wjsvz+/X61atcrZZ5+ds88+O08++WR++MMf5oQTTkifPn0yePDgD3VOAIBVgTuAAIAmc/q4B/PLe6dn0b+XTr39nq5JkyblF7/4xbseu8suu6QoivTu3TuPPPJIklSXYG2yySbveNw222yTG2+8sdFyraZ4K9eGG26YCy+8MC1btqzOBwDgo8odQABAk/n1X55d6ni7vkMyfPjw6rNzJk+enKeeeirnnHNOkuSxxx7L5ptvnr59++avf/1r+vTpk1tuuSUXX3xxkuSggw56x2t+7Wtfy7bbbpsDDzwwRx99dB566KH85Cc/+VDzHzZsWLbeeuv07ds3dXV1GTNmTBYuXJgdd9zxQ50PAGBV4Q4gAKDJLHqHhyZ33Gl4xowZU12adfTRR+dLX/pSWrRokS222CLXXHNNBg0alNdeey2f/OQnc+edd2afffbJjBkzkiSbbrrpO16zvr4+V199daZMmZKhQ4dm3Lhxueaaaz7U/LfbbruMGzcuhx56aPbZZ59Mnjw5119/ferr6z/U+QAAVhXFO73dYnmqr6+vTJo0aYVfFwBYvnqf+tulRqBmRZF/fHOPlTAjAIDVR1EUkyuVylL/y5U7gACAJnPItut8oHEAAFYMzwACAJrMOUM3T5LqW8CaFUUO2Xad6jgAACuHJWAAAAAAJWAJGAAAAMBqTAACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAOAjpiiK9/w3YcKE5TqHXr165aSTTmrSc06bNi1FUeSmm25q0vMCkDRf2RMAAAA+mIkTJ1b/bmhoyIABA3L66adnyJAh1fFNNtlkuc5h7Nix6dy583K9BgBNRwACAICPmH79+lX/njt3bpKkd+/ejcb/06JFi7Jo0aK0aNGiyebQt2/fJjsXAMufJWAAAFAyw4cPT319fcaNG5dNN900rVq1yl/+8pckyaWXXpoNN9wwLVu2zAYbbJDvfOc7jY4dOXJkunTpkrvvvjtbbbVVWrVqlS233DJ33XVXo/2WtgTszjvvzM4775y2bdumQ4cO2WmnnTJlypQkycyZM3PUUUflYx/7WOrq6rLRRhvl9NNPz5tvvrkcfwkA3iYAAQBACU2bNi0nn3xyTj311Pzud7/L+uuvnyuuuCLHH3989t577/zmN7/JAQcckK9+9as5//zzGx07b968fOYzn8kXvvCFXHfddenYsWN23333/POf/3zH602YMCG77LJLamtr87Of/SzXXHNNdthhh8yYMSNJ8tJLL6VTp0759re/nVtuuSUjRozIlVdemeOPP365/g4AvMUSMAAAKKGXX345d9xxR7bccsskyeLFizNy5MgMHz48F110UZJkt912y7/+9a9885vfzAknnJBWrVoleeu5Queee24OPfTQJMnOO++cddddNxdffPESsehtp556arbYYovceuutKYoiSTJ48ODq9s033zwXXnhh9fP222+fNm3a5Kijjsr3vve9Jl2eBsCS3AEEAAAl1KNHj2r8SZLnnnsuzz//fA444IBG+x100EF59dVX8+CDDzYaHzZsWPXvtm3bZuDAgbnvvvuWeq3XX389f/nLX3LEEUdU489/q1Qqufjii7PJJpukrq4utbW1+fSnP5033ngj06dP/5DfEoD3SwACAIASWmuttRp9njlz5lLH3/48e/bs6ljbtm1TV1fXaL+uXbtWz/HfXnnllVQqlXTr1u0d53PxxRfnpJNOyrBhwzJ+/Pjcd999+f73v58kmT9//vv8VgB8WJaAAQDAR8S4KTMy6tbH8/ychnTvWJcRg/pk1w07LHXf/74T5+04M2vWrEbjL7zwQpKkU6dO1bG5c+emoaGhUQSaNWvWOwaeNdZYIzU1Ne8YiJLkuuuuy/77759zzz23OvbII4+84/4ANC13AAEAwEfAuCkzcuoND2bGnIZUksyY05BTb3gwv/n78+/r+J49e6Z79+657rrrGo1fe+21ad++fTbffPNG42PHjq3+PXfu3Nx+++35xCc+sdRzt2nTJttuu21+/vOfp1KpLHWfhoaGtGzZstHYVVdd9b7mDsCycwcQAAB8BIy69fE0LFjUaKxhwaJccseT7+v4mpqajBw5Mp///OfTuXPnDBw4MH/605/ygx/8IOedd171AdBJUldXl9NOOy1z585N9+7dc+GFF+bNN9/Ml7/85Xc8//nnn59dd901u+++ez73uc+lTZs2mThxYurr67Pnnntm4MCB+e53v5ttt902vXv3zlVXXZWnnnrqw/0YAHxgyxyAiqJoleTOJC3/fb4xlUrlzGU9LwAA8P89P6dhqeMz/7X08aU55phjMn/+/FxyySW55JJL0rNnz1x00UX5yle+0mi/1q1b5+c//3mOP/74PProo9l4443z29/+9l2f8bPjjjvm9ttvzxlnnJHPfOYzadGiRfr27ZuhQ4cmSb7+9a/nxRdfzOmnn54k2XffffPd7343e+211/uePwAfXvFOt2i+7xO8tbi4TaVSmVsURW2Su5J8uVKp3PtOx9TX11cmTZq0TNcFAIDVyfbn/yEzlhKBenSsy92nDGiy64wcOTKXXnppXnrppSY7JwArRlEUkyuVSv3Sti3zM4Aqb5n774+1//63bFUJAABoZMSgPqmrbdZorK62WUYM6rOSZgTAR0mTPAS6KIpmRVH8LcmsJLdXKpW/LGWfzxVFMakoikkvvvhiU1wWAABWG0P79sg39908PTrWpchbd/58c9/NM7Rvj5U9NQA+ApZ5CVijkxVFxyRjkxxfqVQeeqf9LAEDAAAAaFrLdQnYf6pUKnOS/DHJ4KY8LwAAAAAf3jIHoKIo1vz3nT8piqIuycAkjy3reQEAAABoGsv8Gvgk3ZL8rCiKZnkrKF1bqVRuaoLzAgAAANAEljkAVSqVB5L0bYK5AAAAALAcNOkzgAAAAABY9QhAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQALBSjBw5MkVRVP917949++23X/7xj3+s1HldcMEFmTBhwkqdAwBAUxOAAICVpkOHDpk4cWImTpyYCy+8MH/729+yyy675PXXX19pcxKAAIAyar6yJwAArL6aN2+efv36JUn69euXddddNzvssEN++9vf5oADDvjA52toaEhdXd37HgcAWF24AwgAWGVsvfXWSZJHHnkkxx13XPr06ZPWrVtn/fXXz7HHHptXX3210f5FUeTb3/52TjjhhKy55prZfPPN33X8pZdeyhFHHJHOnTundevW2WmnnTJp0qTq+Xr16pWXX345Z511VnVpmruBAIAycAcQALDKmDZtWpLkYx/7WP75z3/m3HPPzZprrplnn3025557bg444IDceuutjY4ZNWpUdtxxx/ziF7/I4sWL33V86NCheeqpp3LhhRemS5cuGTVqVHbeeedMmTIlG2ywQcaOHZudd945+++/fz772c8mSTbZZJMV8+UBAJYjAQgAWKkWLlyYJHn66afzpS99Ke3atcuuu+6aww47rNE+66+/fvr375/p06dn3XXXrW7r1q1brrnmmiXO+9/jt9xyS+6+++5MmDAhn/rUp5IkAwYMSK9evTJq1Kj8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JUccccQS8ec/7bbbbtW/O3funK5du1bvAHriiScyffr0HHjggVm4cGH134ABAzJ//vw89NBbN5PecccdGTZsWGpqaqr7rL/++unVq1fe/o8IW265ZUaPHp0LLrggDzzwQP77P2rccccdGThwYNq3b189R7t27bL11lvHf4gAAGB1ssKeAVQUxeeKophUFMWkF198cUVdFoAm9Morr6RSqaRbt27vul/Hjh0bfW7RokXmz5+fJHnppZeSJHvssUdqa2ur/9Zff/0kybPPPlvd71vf+lajfWpra/P0009X9zn99NNz7LHH5rLLLssWW2yRddZZJ5dcckn1ui+99FKuueaaJc7xxz/+sXoOAABYHTRfUReqVCqXJ7k8eWsJ2Iq6LgDLZtyUGRl16+N5fk5D1mqd1NTUZObMmR/6fG8vxbr88svTt2/fJba/HYI6deqUYcOG5bOf/ewS+3Tp0iVJ0qpVq5x99tk5++yz8+STT+aHP/xhTjjhhPTp0yeDBw9Op06dsvfee+eMM85Y4hzt2rX70N8BAAA+alZYAALgo2fclBk59YYH07DgrYcq/3Ne0rJ7n3z3hz/Jcccd967LwN5Jnz590qNHj0ybNi3HHHPMO+63yy675OGHH87WW2/9vq6z4YYb5sILL8z3v//9PPLIIxk8eHB22WWXXHvttdl0001TV1f3gecKAABlIQAB8I5G3fp4Nf68rf2OR+Qf15ye3XffPZ/73OfSpk2bTJw4MfX1S33W3BJqampy0UUX5bDDDsurr76a3XffPS1atMjTTz+dcePGZcyYMWndunVGjhyZT3ziExkyZEiOOuqodOnSJTNmzMjtt9+e4cOHZ6eddsqwYcOy9dZbp2/fvqmrq8uYMWOycOHC7LjjjkmSE088Mb/85S8zYMCAHH/88enRo0deeOGF/OlPf0r//v1zyCGHNPlvBgAAq6ImCUBFUfw6yU5JuhRF8VySMyuVyk+a4twArDzPz1nyVemt1tksax34jcx77rf5zGc+kxYtWqRv374ZOnRo9fk+7+Wggw5K+/btc9555+WnP/1pmjVrlo997GPZc889q2/82mijjXLvvffm9NNPz+c+97k0NDSkR48e2WWXXbLBBhskSbbbbrtcc801GTVqVBYvXpxNNtkk119/fTVGdenSJffee29OO+20fOUrX8mcOXPSrVu39O/fPx//+Meb6FcCAIBVX5O8Bv6D8hp4gI+G7c//Q2YsJQL16FiXu08ZsBJmBAAAvJPl/hp4AMppxKA+qatt1misrrZZRgzqs5JmBAAAfBieAQTAOxrat0eSVN8C1r1jXUYM6lMdBwAAPhoEIADe1dC+PQQfAAD4iLMEDAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAlaKoihy6aWXruxpAAAArBaar+wJAKuniRMnZv3111/Z0wAAAFgtCEDAStGvX7+VPQUAAIDVhiVgQJMbPnx46uvrM27cuGy88cZp1apV+vfvn0ceeaS6z38uAZswYUKKoljqv2nTpmX06NHvuP1tF110UbbZZpt06NAha621Vvbaa6889dRTK/y7AwAArIrcAQQsF88880xOPPHEfOMb30hdXV3OPPPMDBo0KE8++WRatWrVaN+tttoqEydObDR20kkn5fHHH88aa6yRIUOGNNq+aNGiHHnkkY32f+6553LcccdlvfXWy6uvvpof/vCH2W677fLkk0+mQ4cOy++LAgAAfAQIQMBy8dJLL2X8+PHZbrvtkiRbb711evfundGjR+cLX/hCo33bt2/faEnYZZddlnvvvTe33XZbNd6sueaa1e0nn3xyZs6cmXvvvbc69p3vfKf696JFizJw4MB07do148ePz+GHH75cviMAAMBHhSVgwHLRtWvXavxJkvXWWy9bb7117rvvvnc97q677soJJ5yQb37zmxkwYMAS26+55ppceOGF+elPf5pNN920On7vvfdm4MCB6dy5c5o3b57WrVtn7ty5eeKJJ5ruSwEAAHxECUDActG1a9eljs2cOfMdj5kxY0b233//DB06NCNGjFhi+wMPPJCjjjoqX/3qV3PAAQdUx6dPn57ddtstlUolP/rRj3L33Xfn/vvvT9euXTN//vym+UIAAAAfYZaAAcvFrFmzljr2n3ft/Kc33ngj++23X7p06ZKf/vSnS2yfPXt2hg0bln79+uX8889vtO2WW27JvHnzMn78+LRp0yZJsnDhwsyePbsJvgkAAMBHnwAENIlxU2Zk1K2P5/k5DXn9wZl5cdas3HPPPdVlYNOnT89f//rXJR7e/LYvfelLeeyxx3Lfffelbdu2jbYtWrQoBx98cBYuXJirr746zZo1a7S9oaEhNTU1ad78//+vtGuvvTYLFy5s4m8JAADw0SQAActs3JQZOfWGB9OwYFGSZN6bi9Ksdfvse+Ah+fYF36y+Baxr164ZPnz4Esf/6le/yk9/+tOcdtppmT17dqOHO/ft2zcXXXRRbr/99nzve9/LP/7xj/zjH/+obu/Xr18GDBhQfTPY0UcfnYcffjgXXnhhOnbsuLy/OgAAwEeCAAQss1G3Pl6NP29r1r5rOu70mYwcOTLPPPNM6uvr86tf/WqJV8AnqT6o+dxzz825557baNvUqVOr248//vgljq1UKtl8880zevTojBw5MmPHjs0WW2yR6667LgcddFBTfUUAAICPtKJSqazwi9bX11cmTZq0wq8LLB/rn3Jz/vN/k7x083ey4KVn0v2IizP1/CErbV4AAACrk6IoJlcqlfqlbfMWMGCZde9Y94HGAQAAWLEEIGCZjRjUJ3W1jR/MXFMUGTGoz0qaEQAAAP/JM4CAZTa0b48kqb4FbItP/19GDOpTHQcAAGDlEoCAJjG0bw/BBwAAYBVlCRgAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEwAc2cuTIdOnSZWVPAwAAeJ8EIAA+sM9+9rO59dZbV/Y0AACA96n5yp4AAMtfQ0ND6urqmux8PXv2TM+ePZvsfAAAwPLlDiCAD2j48OGpr6/PzTffnE022SStW7fOkCFDMnv27Dz11FPZeeed06ZNm9TX1+eBBx6oHnfRRRdlm222SYcOHbLWWmtlr732ylNPPbXE+ceOHZtPfOITqaurS+fOnbPHHnvkmWeeSZI89thjOfjgg7POOuukdevW2XTTTXPxxRdn8eLF1eMnTJiQoihy6623Zu+9907btm1z3HHHJUn+9re/ZZdddknr1q2zxhpr5NOf/nReeOGF6rHTpk1LURS59tpr8/nPfz4dOnRIz549c+aZZza6hiVgAADw0SIAAXwI06dPz9e//vWcc845ufzyy3PPPffkc5/7XA4++OAcfPDBGTNmTBYuXJiDDz44lUolSfLcc8/luOOOy/jx43PFFVdk0aJF2W677fKvf/2ret5f/OIX2XfffdO7d+9ce+21ufLKK7PRRhvlxRdfTJLMmDEjffr0yWWXXZbf/va3OeaYY3LmmWfmW9/61hJzPProo7PFFlvkxhtvzNFHH50XX3wxO+20U+bNm5df/epX+d73vpc//elPGThwYN58881Gx5588slp27ZtxowZk8985jM5++yzM2bMmOX4iwIAAMuTJWAAH8Ls2bMzceLE9O7dO0nywAMPZNSoUfnZz36Www8/PElSqVQyZMiQPPbYY/mf//mffOc736kev2jRogwcODBdu3bN+PHjc/jhh2fx4sU55ZRTMmzYsPz617+u7rv33ntX/95ll12yyy67VM/fv3//zJs3L1dccUVOPfXURnM84IAD8o1vfKP6+ZRTTkmS3HrrrWnfvn2SZMMNN0y/fv1y/fXX55BDDqnuu+OOO+aiiy5KkgwcODC33HJLbrjhhhx44IHL/uMBAAArnDuAAD6EXr16VeNPkmywwQZJkgEDBiwxNmPGjCTJvffem4EDB6Zz585p3rx5Wrdunblz5+aJJ55Ikjz++ON5/vnnc+SRR77jdefPn58zzzwzG2ywQVq2bJna2tqcdtppmTp1ahYuXNho3yFDhjT6fN9992W33Xarxp8k2XbbbdOrV6/cddddjfbdbbfdGn3eZJNN8txzz737jwIAAKyyBCCAD6Fjx46NPrdo0WKJ8bfH5s+fn+nTp2e33XZLpVLJj370o9x99925//7707Vr18yfPz9J8vLLLydJunXr9o7X/drXvpYLL7wwn/vc5/Lb3/42999/f04//fTqdf7TWmut1ejzzJkzlxh7e7/Zs2e/5/f77/MDAAAfHZaAAbwP46bMyKhbH8/zcxry+oMz075hwQc6/pZbbsm8efMyfvz4tGnTJkmycOHCRuGlc+fOSd4KNe/kuuuuy/HHH5+TTz65OnbzzTcvdd+iKBp97tatW2bNmrXEfi+88EK23nrr9/9lAACAjxx3AAG8h3FTZuTUGx7MjDkNqSSZ9+aizJjTkHFTZrzvczQ0NKSmpibNm///7n7ttdc2WrbVp0+f9OjRIz/72c/e9TwtW7asfl60aFGuvvrq9zWHbbfdNrfeemtee+216tj999+fadOmpX///u/7uwAAAB89AhDAexh16+NpWLCo0djiSiWjbn38fZ9jwIABWbRoUY488sj8/ve/z3e/+92ccsopjZZa1dTU5IILLsj111+fT3/607npppty880356tf/WomTZqU5K0HMn//+9/PL37xi9x8883Za6+98sYbb7yvOZx44olJkkGDBmX8+PG56qqrsu+++2bzzTfPfvvt976/CwAA8NEjAAG8h+fnNHyg8aXZfPPNM3r06PzlL3/JnnvumV/96le57rrr0qFDh0b7HXroobn++uvz2GOPZf/998/hhx+exx57LGuuuWaS5Hvf+1522GGHHHvssTnqqKOy2WabLfH2r3ey5ppr5o9//GNatWqVQw45JMcee2x22GGH3H777dXnFQEAAOVUVCqVFX7R+vr6ytv/NRtgVbf9+X/IjKXEnh4d63L3KQOWcgQAAMCKVxTF5EqlUr+0be4AgmVw9tlnp0ePHqmpqcnw4cOX6VwjR45Mly5dqp+feOKJjBw5MnPmzFm2SbLMRgzqk7raZo3G6mqbZcSgPitpRgAAAB+MO4DgQ5o0aVK22WabnHfeedlpp53StWvX9O7d+0Of77nnnmv0Nqabbrope+21V6ZOnZpevXo10az5sP7zLWDdO9ZlxKA+Gdq3x8qeFgAAQNW73QHkNfDwIT322GNJkmOPPTbt27df6j4NDQ2pq6t7X+fr2bNnevbs2WTzo2kN7dtD8AEAAD6yLAGDD2H48OE57LDDkiQdOnRIURSZMGFCiqLIrbfemr333jtt27bNcccdl2nTpqUoitx0001LnKO+/v+H2f9cAjZhwoTstddeSZL1118/RVG4CwgAAIAPzR1A8CGcccYZWWeddXLOOefkD3/4Q+rq6jJr1qwkydFHH50jjzwyJ5xwQlq1avWhzr/VVlvlwgsvzEknnZQbbrgh3bp1S8uWLZvyKwAAALAaEYDgQ+jdu3f1eT/bbLNN2rZtmwkTJiRJDjjggHzjG9+o7jtt2rQPfP727dunT5+3HjDct29fd/8AAACwTCwBgyY2ZMiQlT0FAAAAaEQAgia21lprrewpAAAAQCMCEDSxoigafX77OUBvvvlmo/FXXnllhc0JAACA1ZtnAMEHMG7KjIy69fE8P6chzf/xyPs6pmvXrqmtrc2jjz5aHZs7d27uueeerLfeeu94XIsWLZIk8+fPX7ZJAwAAsNpzBxC8T+OmzMipNzyYGXMaUknyyrwFSZLf/P35dz2upqYm++yzT77zne/kl7/8ZW666abstddeqaure9fj3n4I9I9+9KP85S9/yYMPPtgk3wMAAIDVjwAE79OoWx9Pw4JFS4xfcseT73nspZdemu233z5f+tKXcuyxx+aQQw7JgAED3vWY9dZbLxdeeGFuuOGGbL/99tlrr70+9NwBAABYvRWVSmWFX7S+vr4yadKkFX5dWBbrn3JzlvY/LUWSqed78xcAAAArV1EUkyuVSv3StrkDCN6n7h2XvmTrncYBAABgVSEAwfs0YlCf1NU2azRWV9ssIwb1WUkzAgAAgPfHW8DgfRrat0eSVN8C1r1jXUYM6lMdBwAAgFWVAAQfwNC+PQQfAAAAPnIsAQMAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AA+MgbOXJkiqKo/lt77bWz55575oEHHvhA5xk9enSKosjcuXPfdb+ddtop+++//7vuM23atBRFkZtuuqk6dsEFF2TChAkfaE4AANAUBCAASqFDhw6ZOHFiJk6cmIsvvjhPPPFEBg4cmNmzZ6+U+XTr1i0TJ05M//79q2MCEAAAK0uTBKCiKAYXRfF4URRPFUVxSlOcEwA+iObNm6dfv37p169fDj744Pz85z/PrFmzcsstt6yU+bRs2TL9+vVLx44dV8r1AQDgPy1zACqKolmS7yfZPckmSQ4pimKTZT0vACyLLbbYIkny7LPPJkkmTpyYvffeO926dUubNm2y5ZZb5qqrrlrqsY8++mh22GGH1NXVZaONNsrYsWOXut/ll1+eXr16pa6uLkOGDMmMGTOq2/57CVivXr3y8ssv56yzzqouVXM3EAAAK0pT3AH0iSRPVSqVpyuVyptJrk6yTxOcFwA+tOnTpydJ1l9//STJM888k+233z4/+clP8pvf/Cb77bdfjjzyyPz6179e4tiDDjoo++yzT2644YZsvvnmOeCAA/L3v/+90T4TJ07M9773vXz729/OT37ykzzwwAMZOnToO85n7Nix6dChQ44++ujqUrWtttqq6b4wAAC8i+ZNcI4eSZ79j8/PJdn2v3cqiuJzST6XJOuuu24TXBYAGlu4cGGSt2LPcccdly233DL77PPWf5M4+OCDq/tVKpXsuOOOee6553LFFVfkkEMOaXSez372sznppJOSJIMGDcomm2ySb37zm7n66qur+8yaNSsTJ06s/t+09dZbL/37988tt9ySwYMHLzG3vn37pnnz5unZs2f69evXtF8cAADewwp7CHSlUrm8UqnUVyqV+jXXXHNFXRaA1cTLL7+c2tra1NbWZoMNNsiUKVNyww03pGXLlkmSV155Jf/7v/+b9dZbr7rf5ZdfnieeeGKJcw0bNqz6d01NTfbZZ5/cd999jfbZaqutGv0Hje233z5du3ZdYj8AAFgVNEUAmpFknf/43PPfYwCwwnTo0CH3339/7r333vzoRz/Km2++mUMPPTSLFy9OkgwfPjzXXHNNRowYkdtuuy33339/jjrqqMyfP3+Jc3Xt2nWJzzNnznzXfd5pPwAAWBU0xRKw+5NsWBTF+nkr/Byc5NAmOC8AvKNxU2Zk1K2P5/k5DVk4aWoWFzWpr69Pkmy77bapq6vL4Ycfnuuuuy777LNPbrrppnz/+9/PF77wheo53o5D/23WrFnp3Llzo8/dunVbYp+lHfff+wEAwKpgme8AqlQqC5Mcl+TWJI8mubZSqTy8rOcFgHcybsqMnHrDg5kxpyGVJK/NX5B5byzKuCn//wbUz3zmM9l0003zrW99K2+88UYWL15cXQ6WJK+99lpuvPHGpZ7/P9/6tXjx4owfPz6f+MQnGu3z17/+tfqg6SS5++67M2vWrCX2+08tWrRY6h1HAACwvDXFHUCpVCq/TfLbpjgXALyXUbc+noYFixqNVf49PrRvjyRJURT5v//7v3z605/OpEmTss022+Tss89O+/btU1NTk/PPPz8dOnTIq6++usT5f/zjH6dFixbZbLPN8uMf/zhPPfXUEm8LW3PNNTNkyJCcddZZmT9/fr72ta9lq622WuoDoN+28cYb5+abb87gwYPTtm3b9OnTJ+3atVv2HwQAAN7DCnsINAA0lefnNLyv8YMOOigbbrhhLrjggvzqV7/Kxz72sRx++OH58pe/nP322y+HH374Us9z9dVXZ+zYsRk6dGj+/ve/55prrknfvn0b7bPddtvl2GOPzQknnJCjjz46m222WcaNG/eu8x41alTatGmTIUOGZJtttsnkyZPf/5cGAIBlUFQqlRV+0fr6+sqkSZNW+HUBKIftz/9DZiwlAvXoWJe7TxmwEmYEAAArX1EUkyuVSv3StrkDCICPnBGD+qSutlmjsbraZhkxqM9KmhEAAKzamuQZQACwIr39nJ+33wLWvWNdRgzqUx0HAAAaE4AA+Ega2reH4AMAAO+TJWAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlA8BEwcuTIdOnSZanbhg8fnvr6+hU8o6W79tprM3r06CY957t9dwAAAN4fAQhoMssjAAEAALDsmq/sCQAsTaVSyRtvvLGypwEAAFAK7gCCEpk5c2aOOuqofOxjH0tdXV022mijnH766XnzzTer+0ybNi1FUeTqq6/OkUcemfbt26dnz5755S9/mSS54IIL0r1796y55pr52te+lsWLF1ePfe6553LggQema9euqaurS+/evXPGGWckeWsp2vXXX58//elPKYoiRVFk5MiR1WPHjx+f+vr6tGrVKmuvvXZOPvnkLFiwoLr97aVed911V7bZZpu0atUq1113XXX7lClT0q9fv7Ru3Tp9+/bNn//85+X1MwIAAJSOO4DgI2ThwoVLjFUqlerfL730Ujp16pRvf/vbWWONNfLEE09k5MiRefHFF/OjH/2o0XFf+9rX8ulPfzrXX399fvrTn+aII47IlClT8swzz+SnP/1pJk+enNNPPz19+/bNwQcfnCQ5/PDD09DQkMsvvzwdO3bM008/ncceeyxJcsYZZ2T69OmZM2dOLrvssiRJz549k7y1NOyQQw7J5z//+Zx33nn5xz/+kVNPPTWLFy/OhRdeWJ3TvHnzcsQRR+Tkk0/ORhttlO7du+cf//hHdfwrX/lK1l577Zx11lnZd99988wzz6R169ZN+yMDAACUkAAEHxEvv/xyamtrl7pt6623TpJsvvnmjYLK9ttvnzZt2uSoo47K9773vbRo0aK6bcCAATnvvPOSJNtuu23GjBmTG2+8MY899liaNWuWwYMHZ/z48Rk7dmw1AN1333359a9/nb322itJstNOO1XP17t373Tq1CmLFy9Ov379quOVSiUjRozI4YcfXg1DSdKyZcsce+yxOfXUU9O5c+ckSUNDQ7797W9nn332afT9GhoacvHFF2fAgAFJkm7duqVv37658847M3jw4A/2QwIAAKyGBCD4iOjQoUPuuOOOJcbPOuuszJw5M8lbseWSSy7J5ZdfnqlTp2b+/PnV/aZPn54NNtig+nmXXXap/t2+ffusueaa+dSnPpVmzZpVxzfYYINMnz69+nnLLbfMqaeempdffjkDBgzIuuuu+57zfuKJJzJ9+vQceOCBje5gGjBgQObPn5+HHnoon/rUp5IkRVFk9913X+IcLVq0aBSbNtlkkyRvLUkDAADgvQlA8BHRvHnzpb7uvXPnztUAdPHFF2fEiBH52te+lk996lNZY401cv/99+fYY49tFIOSpGPHjo0+t2jRYqlj/3ncNddck9NOOy1f+cpXMmfOnGyxxRa56KKLGsWk//bSSy8lSfbYY4+lbn/22Werf6+xxhqN7lJ6W7t27VJT8/8fWfb2Pv/9nQAAAFg6AQhWUeOmzMioWx/P83MasnDS1Ly5aPF7HnPddddl//33z7nnnlsde+SRR5psTj169Mjo0aOzePHi3HfffRk5cmT23nvvTJ8+vbqM67916tQpSXL55Zenb9++S2xff/31q38XRdFkcwUAAOD/E4BgFTRuyoycesODaViwKEny2vwFmffGooybMiND+/Z4x+MaGhrSsmXLRmNXXXVVk8+vpqYm/fr1y5lnnpntttsuzzzzTDp37rzEHUNJ0qdPn/To0SPTpk3LMccc0+RzAQAA4L0JQLAKGnXr49X487bKv8ffLQANHDgw3/3ud7Ptttumd+/eueqqq/LUU081yZz+9a9/ZdCgQTn88MOz0UYb5Y033shFF12UtddeO//zP/+TJNl4440zfvz4jBs3Lj179kz37t3TvXv3XHTRRTnssMPy6quvZvfdd0+LFi3y9NNPZ9y4cRkzZow3eQEAACxnAhCsgp6f0/CBxt/29a9/PS+++GJOP/30JMm+++6b7373u9W3di2LVq1aZfPNN88ll1ySZ599Nq1bt06/fv1y2223pa6uLknypS99KVOmTMlRRx2VV155JWeeeWZGjhyZgw46KO3bt895552Xn/70p2nWrFk+9rGPZc8991zqM38AAABoWkWlUlnhF62vr69MmjRphV8XPiq2P/8PmbGU2NOjY13uPmXASpgRAAAAq7qiKCZXKpUl3x6UpGZpg8DKNWJQn9TVNms0VlfbLCMG9VlJMwIAAOCjzBIwWAW9/Zyft98C1r1jXUYM6vOuz/8BAACAdyIAwSpqaN8egg8AAABNwhIwAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACi5ZQpARVEcUBTFw0VRLC6Kor6pJgUAAABA01nWO4AeSrJvkjubYC4AAAAALAfNl+XgSqXyaJIURdE0swEAAACgyXkGEAAAAEDJvecdQEVR3JFk7aVsOq1SqYx/vxcqiuJzST6XJOuuu+77niAAAAAAy+Y9A1ClUtm1KS5UqVQuT3J5ktTX11ea4pwAAAAAvDdLwAAAAABKbllfAz+sKIrnknwyyc1FUdzaNNMCAAAAoKks61vAxiYZ20RzAQAAAGA5sAQMAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBaBUwevToFEWRuXPnNsn55s6dm6IoMnr06OpYr169ctJJJzXJ+QEAAICPFgFoFTBkyJBMnDgxrVu3XtlTAQAAAEqo+cqeAMmaa66ZNddcc2VPAwAAACgpdwAtB4MHD05RFLn66qvz8Y9/PG3atEn79u1TU1OTOXPmJEnmzZuXzp07p23btqmtrU1RFBk/fnySZNq0aSmKItdee2223377NGvWLEVRpFOnTvn2t7/d6FoPPfRQttpqq9TU1KQoiqy55pq566673tc8//znP+dTn/pUWrdunc6dO+eYY47Ja6+9Vt0+Z86cfPazn0337t3TqlWrrLvuujnmmGOa5kcCAAAAVhh3AC0HXbp0SZKccsop+da3vpWampoceOCBKYoid911V/bcc88cccQRmT17dr7whS+krq4u3/nOd7L//vvnj3/8Y3r27Jkk+eIXv5jZs2dnv/32S7NmzXLttdfmpJNOyptvvplTTjklTz31VPr165d58+blk5/8ZHbaaaf8+Mc/zj777POec7z77ruz6667ZujQoRkzZkxefvnlnHLKKXnllVcyZsyYJMmJJ56Ye+65J9/5zney9tpr59lnn82dd965/H44AAAAYLkQgJaD5s3f+ln79++fgw46KH/4wx/Srl27vPbaaxk/fnx69+6d66+/PkVR5Fvf+lZuuOGGJMmGG26Yb3zjG/nRj36UJGloaMjw4cNz5ZVXJkkef/zxzJ07N9/85jdzwgkn5KyzzkpRFOnTp0/uuuuuFEWR4cOHp0+fPu85x1NOOSXbbbddrrnmmupYjx49sssuu+Shhx7KZpttlvvuuy/HHntsDjrooOo+n/nMZ5rsdwIAAABWDEvAlpOOHTvmwQcfTJLceeed2XbbbZMk99xzT+6///5UKpV8/OMfT/v27avHDBs2rNHyrYaGhhxwwAHVz5tssknq6ury6quv5sEHH8wdd9yRmpqa7LXXXlm0aFEWLlyY9ddfPz169HjXuc2bNy8TJ07MgQcemIULF1b/9e/fP7W1tZk8eXKSZMstt8yoUaNy2WWX5Yknnmiy3wYAAABYsQSg5aRLly556KGHMmfOnPz5z3+uBqAnnngi06dPT01NTT71qU81OqZr166ZN29e3njjjerYWmutVf27RYsWqVQqSZLZs2fnpZdeyquvvppRo0altra2+u+5555717m98sorWbRoUb70pS81Oq5ly5ZZsGBBnn322STJpZdemqFDh+bss89Onz59suGGG+bqq69ukt8HAAAAWHEsAVtO2rZtmySZMGFC7r333nz5y19OkrRq1SqzZ8/O4sWL84lPfKLRMbNmzUrr1q3TsmXLRmP/acGCBUmSTp06pVOnTpk3b1723XffHH/88dV9pk6dmgMPPPAd59axY8cURZGRI0dmjz32WGJ79+7dq/t997vfzXe/+9088MADueCCC/LpT386H//4x7PJJpt8kJ8DAAAAWIkEoCZy+rgH8+u/PJtFlUpenvxc2ja8mc022yzf+c530qxZs2y66aZJ3lrG9ec//znJW3fx/Kdx48alf//+1c+dOnXKddddl91337069sorr6R9+/bZfPPNs8suu+S2227L/fffn6233jpFUSRJbr311neda5s2bdKvX788/vjj+frXv/6+vt/HP/7xjBo1KldddVUee+wxAQgAAAA+QgSgJnD6uAfzy3unVz9Xksx+/c302OjjufN3V2fQoEFp1qxZkmTTTTfNlVdemXbt2uW0005LTU1Nnn766SRvLQ97+wHQSXLooYfm+9//fjp37pyBAwfmr3/9a1588cV885vfTKtWrTJy5MjceOONefTRR7Pddttl2LBh+dvf/pbf/OY37znnCy64ILvssktqamqy//77p127dpk+fXpuvvnmnHvuudloo43Sv3//DBs2LJtttlmKosgVV1yRNm3aLHHnEgAAALBqE4CawK//8uxSx59tsV6SZMcdd6yOvX0n0NChQ9OhQ4ecffbZ1TuBrrvuuvTv3z/Tpk1LkgwaNCgbbbRRLrnkklxyySVp2bJlevbsmVNOOSVJstFGG2XSpEkZPnx47rvvvtx7771p1apVBg8enHHjxr3rnPv3758777wzZ555Zg477LAsWrQo6623XgYPHlx97tAnP/nJjB49OtOmTUuzZs3St2/f/O53v6u+ph4AAAD4aCjefqjwilRfX1+ZNGnSCr/u8tLrlJvfcdu084eswJkAAAAAq6uiKCZXKpX6pW3zFrAm0Ozfz955v+MAAAAAK5IA1AQO2XadDzQOAAAAsCJ5BlATOGfo5klSfQtYs6LIIduuUx0HAAAAWJk8AwgAAACgBDwDCAAAAGA1JgABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwABAAAAFByAhAAAABAyQlAAAAAACUnAAEAAACUnAAEAAAAUHICEAAAAEDJCUAAAAAAJScAAQAAAJScAAQAAABQcgIQAAAAQMkJQAAAAAAlJwABAAAAlJwA1ASGDx+e+vr6D338yJEj06VLlyaZy0knnZRevXo1ybkAAACAchCAAAAAAEpOAFqFVSqVzJ8/f7leY9GiRXnzzTeX6zUAAACAlUsAagKvvPJKnnzyybRr1y41NTWpqalJ796988gjj+Tmm29O//79UxRFWrdunX79+uW2225LsuTSsbeXgt1+++3p2rVrampq0qFDh6y//voZNGhQevfunbq6uuy8886ZMmVKiqJIv3790rZt23Tr1i3nnntuHnzwwTz//PNp2bJl1ltvvVxwwQWN5vr2NceNG5dNN900rVq1yl/+8pcV+nsBAAAAK1bzlT2BMvjDH/6QN954I506dcpxxx2Xl19+OTfeeGMGDRqUE088MbvsskvuvvvunHrqqXnllVey++67584771zquebNm5djjjkm//M//5MvfelL6d27d6ZOnZozzzwza621VsaOHZtHH300Bx10UJLkwQcfzMUXX5y11147X/7ylzN16tR06NAh1113XSZPnpwzzjgjrVu3znHHHVe9xrRp03LyySfn61//etZee+2sv/76K+R3AgAAAFYOAWgZvfTSS5k7d26S5IYbbsh2222XJDnttNOqd+wMGzYsZ599drbYYovsscceefjhh/OTn/xkqedraGjIJZdckn322ac6tt9++2X99dfP1KlTs8kmm2Tw4MF59tln853vfCeHH354jjnmmLz66qt54YUX0qpVq3Ts2DEDBw7MwIEDM2/evJxzzjn54he/mGbNmiVJXn755dxxxx3Zcsstl++PAwAAAKwSLAFbRp06dUqbNm1SW1ubZ599NrNmzUqSrLfeetl6663zxz/+MV/96leTJEOHDk1tbW1uu+22PPHEE0s9X1EU2X333fOLX/wiffv2Tdu2bXPDDTdk6tSpSVI9bs0110ySbLXVVkmSiRMnZt68edlpp52SJAsXLszChQszYMCAvPDCC3nuueeq1+jRo4f4AwAAAKsRAWgZ1dTUZODAgamrq8tRRx2VtddeOzvssEOmTJmSNddcM7fcckv++te/JknOPffc3H///dl9993f8eHOa6yxRm6++eYcfvjh+eQnP5nrrrsutbW1GT58eJJUj2toaEiS1NbWJnnrTqQkueWWW/LMM8+ktrY2tbW12XnnnZMkzz77bPUaa621VtP/EAAAAMAqyxKwJtChQ4e0atUqzz33XP785z/na1/7WoYMGZIuXbrk1VdfzQ9+8IN8+tOfTp8+fVJfX1+NN6+88soS5yqKItddd1223XbbXHbZZUmS7t27L/Gmrrq6uiTJggULkrx1J1KS7LDDDnnqqady4403Ntq/T58+ja4BAAAArD4EoA/p9HEP5td/eTaLKpW8PPm5zJ01K/fff38GDBiQE088MYceemh1Odhaa62V2traPProo3nmmWdy9913Z7PNNss999yT9dZbb4lzNzQ0pGXLltXP22yzTX73u9812ufFF19MkurdRZ/85CfTqlWrTJ48OWuuuWajt4sBAAAAqzcB6EM4fdyD+eW905Mkb86amnlTp6SobZXd9twnxxzxmYwbNy6tWrXKGmuskZqamowYMSKf+MQn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7//+Lz/84Q+z3377Ze7cubnggguW7xcEAACAVYzXwLPCbX/+HzJjKRGoR8e63H3KgJUwIwAAAPjo8xp4VikjBvVJXW2zRmN1tc0yYlCflTQjAAAAKDfPAGKFG9q3R5JU3wLWvWNdRgzqUx0HAAAAmpYAxEoxtG8PwQcAAABWEEvAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAKDkBCAAAACAkhOAAAAAAEpOAAIAAAAoOQEIAAAAoOQEIAAAAICSE4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCAAAAFjt9erVK0VRLPGvRYsWad68eX71q1+lV69eOemkk6rHXHvttRk9evQS59pvv/1yzjnnrMDZvzcBCAAAAODfiqJI//79s++++6a2tjYLFixIpVLJFVdckbFjx+Z///d/q/u+UwAaP358xowZswJn/d4EIAAAAGC1N2/evCTJj3/84/z5z3/O2muvncWLFydJevTokccffzwf//jHs+66667MaX5oAhAAAACw2nv11VeTJEcddVROPPHE/PCHP8xPfvKTJMluu+2WmTNnZo011sgnPvGJbLLJJqmpqcn111+fP/3pT9XlYkOHDk1RFFm0aFH+/ve/V8dra2szYsSIXHzxxSmKIm3atEmzZs3SuXPnrLHGGqmrq8uQIUMyY8aMDB8+PPX19enTp086deqUNm3apH///nn44YeTJMOHD0/fvn0/8PcTgAAAAIDV2oIFC/LGG28kSU477bRcfPHF+fGPf5xPfOITSZLtttsuSbJw4cLMmzcvixYtSrt27dKuXbskScuWLdOqVatssskm1XO2aNEiNTU16dGjRxYuXJgHHnggI0eOTJJ06dIlHTt2TG1tbebOnZuDDjooDzzwQIYOHZokmT59eubNm5d58+blpz/9aWbNmpWDDjoor732WsaMGZOjjjrqA39HAQgAAABYrb388svVv88777z87//+b7bffvt86UtfSrt27bL77rsnSRYvXpw+ffrkiSeeyI033pgePXqkWbNmeeONN9KyZcvcc889Sd56jtCCBQty/vnnZ/r06enTp0/atm1bvcto/fXXz6uvvpr77rsvp556am655ZZcddVVmTRpUmbMmJHZs2fnxhtvTLNmzTJv3rxccMEFefjhh/Pd7343CxYsyKGHHvqBv6MABAAAAPAfLrnkkvTp0ydPP/10rrnmmnTr1q267dFHH03z5s2z995757HHHsuiRYuSJJtuummefPLJJG8FoEqlkr333js1NTXZZ599cvfdd6dSqSRJKpVK+vbtm+7du2fAgAF54YUXst5666Vr16556aWX0qtXr/Tt2zf7779/Ro8eXb2z6Oqrr87ee++dzp07f+DvJAABAAAAq7X/DCq33357evXqla5du+YPf/hDdt9998yfP7+6/dFHH03r1q3zi1/8Ir169UqzZs2SJK1bt87cuXMbnXfNNddMknTt2jWzZ8+ujt955525//77U1tbm5133jlJ8uyzz6Zr166ZN29eOnbsmCQ5+uij8+c//zn//Oc/kyQPPfTQh1r+lSTNP9RRAAAAAB9hA789IU/Oer36uWhWm8qiBdl1113zpz/9Kdttt10GDx6cu+++O5MnT07y1hKw2tratGzZMnvvvXdOPPHE6vGvvfZao2VeSfLiiy+mU6dOmTVrVjp16pQXXnghSbLVVltl/vz5+dnPflbdt0+fPpk1a1a6d+9eHdtxxx2z4YYbVl8p36lTp+y2224f6vu6AwgAAABYrfx3/EmStKhLkvzsZz/Luuuum1tvvTUvv/xydtttt3z1q1+t3unTvHnzvPjii5kwYUJeeuml6qviH3744Wy44YbV0xVFkfHjx2fx4sUZP358tttuuxRFkSRp165dnnjiiXTt2jX19fWpr6/PAw88kFmzZqVLly6NpnXUUUfl+uuvT5IMGDCgOo8PSgACAAAAVitLxJ8kNbUtk7y17Gro0KEZO3Zsdthhh/z973/Po48+mm7dumXBggVpaGjIGmuskd122y2vv/569bk+8+fPz/bbb58k1dBz6qmnZr311svjjz+euXPnpn379kmSqVOnpn379tlxxx1z9NFHZ5tttsnBBx+crbbaKj169Gg0ryOOOKJ659Cuu+76ob+zAAQAAADwb4sWLcr48eNzxhln5De/+U3atm2bmpqafPzjH0/r1q3TvHnz/Otf/8qiRYuycOHC6nELFy7Mww8/nCT55je/mZqamixevDjPPfdcmjdvno033jgnnHBC6urqMnv27MyZMyezZs3KL3/5y/ztb3/LZpttlnHjxi0xn7XXXjtbbrllkiwRhz6I4u1StSLV19dXJk2atMKvCwAAANDrlJvfcdu084d86POOHj06Rx55ZPV5QP9t1113zYIFC1IURbp06VJ9ts+7mT17dnr06JFLL700Rx999LvuWxTF5EqlUr+0bR4CDQAAAKxWNuzaZqnLwDbs2qbJrvHHP/4xf/nLX7LVVltlwYIFueaaa/L73/8+1113XS699NL3PP61117LI488kksuuSTt2rXLIYccskzzsQQMAAAAWK3cfuJOS8SeDbu2ye0n7tRk12jbtm3GjRuXAw44IPvuu2/++te/ZvTo0dl///3f1/GTJ09Ov379cs899+TnP/95WrduvUzzsQQMAAAAoATebQmYO4AAAAAASk4AAgAAACg5AQgAAACg5AQgAAAAgJITgAAAAABKTgACAAAAKDkBCPh/7dzP6y11HQbw50GDFhktFAKvVNtLBYFI4KJICa1LrouCaFugYITlnxBUi4QQN0JCCCpBEGXQtqhMA/uFRFlSqLSoXUjvFudEQve2ypkvn3m9VmfmHJhn8+Ywz3zmAwAAwOIUQAAAAACLUwABAAAALE4BBAAAALA4BRAAAADA4hRAAAAAAItTAAEAAAAsTgEEAAAAsDgFEAAAAMDiFEAAAAAAi1MAAQAAACxOAQQAAACwOAUQAAAAwOIUQAAAAACLUwABAAAALE4BBAAAALA4BRAAAADA4hRAAAAAAItTAAEAAAAsTgEEAAAAsDgFEAAAAMDiFEAAAAAAi1MAAQAAACxOAQQAAACwOAUQAAAAwOIUQAAAAACL68xsf9H2lSR/2PzC/+3GJK/uHQIOyOzB9swdbM/cwfbMHUf3jpm56Wpf7FIAXRRtfzozt+6dA47G7MH2zB1sz9zB9swdXJtXwAAAAAAWpwACAAAAWNzRC6CH9w4AB2X2YHvmDrZn7mB75g6u4dB7AAEAAAAcwdFXAAEAAAAsTwEEAAAAsDgF0Fnb+9tO2xv3zgKra/vltr9u+4u2T7V9296ZYFVt72r7m7YvtH1g7zxwBG1vafvDtr9s+3zbe/fOBEfR9rq2P2/7nb2zwEWjAMrpTzrJh5O8uHcWOIink7x7Zt6b5LdJvrhzHlhS2+uSPJTk7iSXk3y87eV9U8EhvJbk/pm5nOT9ST5r9mAz9yb51d4h4CJSAJ18NckXktgRGzYwM9+fmdfOhz9KcmnPPLCw25K8MDO/m5l/JPlWknt2zgTLm5k/z8wz589/z+lm9OZ9U8H62l5K8tEkj+ydBS6iwxdAbe9J8tLMPLd3FjiozyT57t4hYFE3J/nj647/FDehsKm270zyviQ/3jkKHMHXcnqw/8+dc8CFdP3eAbbQ9gdJ3n6Vrx5M8qWcXv8C/o/+19zNzLfPv3kwp2Xyj22ZDQC20PYtSZ5Ict/M/G3vPLCytleSvDwzP2v7wZ3jwIV0iAJoZu682vm270nyriTPtU1Or6E80/a2mfnLhhFhOdeau39r++kkV5LcMTNev4Q3xktJbnnd8aXzOeAN1vZNOZU/j83Mk3vngQO4PcnH2n4kyZuTvLXtN2fmkzvngguj7rv+o+3vk9w6M6/unQVW1vauJF9J8oGZeWXvPLCqttfntNH6HTkVPz9J8omZeX7XYLC4np4sPprkrzNz385x4HDOK4A+PzNXdo4CF8rh9wACdvH1JDckebrts22/sXcgWNF5s/XPJfleTpvQPq78gU3cnuRTST50/p979rwqAQB2YwUQAAAAwOKsAAIAAABYnAIIAAAAYHEKIAAAAIDFKYAAAAAAFqcAAgAAAFicAggAAABgcQogAAAAgMX9C/NnQ6E9yoN5AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1440x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt \n",
    "from sklearn.decomposition import PCA \n",
    "import numpy as np \n",
    "\n",
    "vocab = nlp(\"Dog Puppy Turtle Rabbit Parrot Cat Kitten Goldfish Mouse Tropical fish Hamsterh burger pizza food cheese wine salad noodles macaroni fruit vegetable\") \n",
    "\n",
    "words = [word.text for word in vocab]\n",
    "\n",
    "vecs = np.vstack([word.vector for word in vocab if word.has_vector ])\n",
    "\n",
    "pca = PCA(n_components=2)\n",
    "\n",
    "vecs_transformed = pca.fit_transform(vecs)\n",
    "\n",
    "plt.figure(figsize=(20, 15))\n",
    "\n",
    "plt.scatter(vecs_transformed[:, 0], vecs_transformed[:, 1])\n",
    "\n",
    "for word, coord in zip(words, vecs_transformed ):\n",
    "    x, y = coord\n",
    "    plt.text(x, y, word, size=15)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sentence similarity with Spacy\n",
    "\n",
    "### Understanding semantic similarity\n",
    "\n",
    "semantic similarity is a metric that's defined over texts, where the distance between two texts is based on their semantics.\n",
    "\n",
    "\n",
    "![](2022-06-17-15-29-44.png)\n",
    "\n",
    "What does Euclidian distance mean for word vectors? First, Euclidian distance has no idea\n",
    "of vector orientation; what matters is the vector magnitude.\n",
    "\n",
    "This is the main drawback of using Euclidian distance for semantic similarity – the\n",
    "orientation of the two vectors in the space is not taken into account.\n",
    "\n",
    "\n",
    "### There's another way of calculating similarity that addresses this problem, called cosine similarity. \n",
    "\n",
    "![](2022-06-17-15-30-43.png)\n",
    "\n",
    "![](2022-06-17-04-11-13.png)\n",
    "\n",
    "Contrary to Euclidian distance, cosine distance is more concerned with the orientation of the two vectors in the space. The cosine similarity of two vectors is basically the cosine of the angle that's created by these two vectors.\n",
    "\n",
    "![](2022-06-17-04-11-13.png)\n",
    "\n",
    "\n",
    "### spaCy uses cosine similarity to calculate semantic similarity. Hence, calling the similarity method helps us make cosine similarity calculations.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.4609855393976771\n",
      "0.9571343794542809\n",
      "0.3738631487509084\n"
     ]
    }
   ],
   "source": [
    "doc1 = nlp(u'the person wear red T-shirt')\n",
    "\n",
    "doc2 = nlp(u'this person is walking')\n",
    "\n",
    "doc3 = nlp(u'the boy wear red T-shirt')\n",
    "\n",
    "\n",
    "print(doc1.similarity(doc2)) \n",
    "\n",
    "print(doc1.similarity(doc3))\n",
    "\n",
    "print(doc2.similarity(doc3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def remove_pronouns(text):\n",
    "    doc = nlp(text)\n",
    "    result = [token for token in doc if token.lemma_ != '-PRON-' ]\n",
    "    return \" \".join(result)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.13 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "36cf16204b8548560b1c020c4e8fb5b57f0e4c58016f52f2d4be01e192833930"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
